<template>
  <div class="main-box">
    <TreeFilter
        ref="treeFilterRef"
        id="type"
        label="name"
        title="字典名称(单选)"
        :data="treeData"
        :default-value="initParam"
        @change="changeTreeFilter"
    >
      <template #default="scope">
        <div class="custom-label">{{ scope.row.data.name }}</div>
        <div class="custom-operation">
          <el-button
              type="primary"
              link
              :icon="Plus"
              v-if="!scope.row.data.id && scope.row.data.type && authButton('/dict/add')"
              @click.stop="openDialog('新增', { type: scope.row.data.type })"
          ></el-button>
          <el-button
              type="primary"
              link
              :icon="EditPen"
              v-if="scope.row.data.id && authButton('/dict/edit/*')"
              @click.stop="openDialog('编辑', scope.row.data)"
          ></el-button>
          <el-button
              type="primary"
              link
              :icon="Delete"
              v-if="scope.row.data.id && authButton('/dict/edit/*')"
              @click.stop="deleteDict(scope.row.data)"
          ></el-button>
        </div>
      </template>
    </TreeFilter>
    <div class="table-box">
      <ProTable ref="proTable" title="字典配置值列表" :columns="columns" :request-api="getTableList" :init-param="initParam">
        <!-- 表格 header 按钮 -->
        <template #tableHeader="scope">
          <el-button
              type="primary"
              :icon="CirclePlus"
              @click="openDrawer('新增', { ...initParam })"
              v-auth="'/dict/value/add'"
          >新增字典值</el-button
          >
          <el-button
              type="danger"
              :icon="Delete"
              plain
              v-auth="'/dict/value/delete/*'"
              @click="batchDeleteValue(scope.selectedListIds)"
              :disabled="!scope.isSelected"
          >
            批量删除
          </el-button>
        </template>
        <!-- Expand -->
        <template #expand="scope">
          {{ scope.row }}
        </template>
        <template #otherText="scope">
          <div class="other-text">
            <el-input
                v-if="scope.row.isEdit"
                size="small"
                ref="otherTextRef"
                v-model="scope.row.otherText"
                :disabled="!authButton('/dict/value/changeOtherText')"
                @change="(val: string) => changeOtherText(val, scope.row)"
                @blur="scope.row.isEdit = false"
            />
            <template v-else>
              <span v-text="scope.row.otherText" />
              <el-button
                  link
                  type="primary"
                  :icon="EditPen"
                  class="column-edit-icon"
                  v-if="authButton('/dict/value/changeOtherText')"
                  @click="editOtherText(scope.row)"
              />
            </template>
          </div>
        </template>
        <!-- sort -->
        <template #sort="scope">
          <el-input-number
              size="small"
              :model-value="scope.row.sort"
              :disabled="!authButton('/dict/value/setSort')"
              @change="(val: number) => changeSort(val, scope.row)"
          />
        </template>
        <!-- status -->
        <template #status="scope">
          <el-switch
              :model-value="scope.row.status"
              active-text="启用"
              inactive-text="禁用"
              inline-prompt
              :active-value="1"
              :inactive-value="0"
              :disabled="!authButton('/dict/value/change_status/*')"
              @click="changeStatus(scope.row)"
          />
        </template>
        <!-- 表格操作 -->
        <template #operation="scope">
          <el-button type="primary" link :icon="View" @click="openDrawer('查看', scope.row)">查看</el-button>
          <el-button
              type="primary"
              link
              :icon="EditPen"
              v-auth="'/dict/value/edit/*'"
              @click="openDrawer('编辑', scope.row)"
          >编辑</el-button
          >
          <el-button
              type="primary"
              link
              :icon="Delete"
              v-if="scope.row.isAdmin !== 1 && authButton('/dict/value/delete/*')"
              @click="deleteDictValue(scope.row)"
          >删除</el-button
          >
        </template>
      </ProTable>
      <DictDialog ref="dictRef" />
      <DictValueDrawer ref="dictValueRef" />
      <ImportExcel ref="importRef" />
    </div>
  </div>
</template>

<script lang="ts">
export default {
  name: "dictManage",
}
</script>

<script lang="ts" setup>
import { ref, onBeforeMount, reactive, nextTick } from "vue";
import { dict } from "./dict";
import { authButton } from "@/hooks/useAuthButton";
import {
  dictValuePageListApi,
  changeValueStatusApi,
  changeValueSortApi,
  changeValueOtherTextApi,
  addDictValueApi,
  editDictValueApi,
  deleteDictValueByIdApi,
  deleteDictValueApi,
  addDictApi,
  editDictApi,
  deleteDictByIdApi,
  dictTreeApi
} from "@/api/modules/dict";
import { CirclePlus, Delete, EditPen, View, Plus } from "@element-plus/icons-vue";
import { useHandleData } from "@/hooks/useHandleData";
import ProTable from "@/components/ProTable/index.vue";
import TreeFilter from "@/components/TreeFilter/index.vue";
import ImportExcel from "@/components/ImportExcel/index.vue";
import { ElMessage } from "element-plus";
import DictValueDrawer from "@/views/system/dict/DictValueDrawer.vue";
import DictDialog from "@/views/system/dict/DictDialog.vue";
import { Recordable } from "@/interface/types.ts";

const { columns } = dict();
const dictList = ref<any[]>([]);
const treeData = ref<any[]>([]);

// 如果表格需要初始化请求参数，直接定义传给 ProTable(之后每次请求都会自动带上该参数，此参数更改之后也会一直带上，改变此参数会自动刷新表格数据)
const initParam = reactive({
  dict_id: undefined,
  dict_type: undefined
});

const treeFilterRef = ref();

onBeforeMount(() => {
  getTreeData();
});

const getTreeData = async () => {
  const res = await dictTreeApi({});
  const data = res.data as any[];
  treeData.value = data;
  data.filter(item => item.children).map(item => dictList.value.push(...item.children));
  treeFilterRef.value.updateTreeData(data);
};

// 树形筛选切换
const changeTreeFilter = (params: any) => {
  console.log(params);
  proTable.value.pageable.pageNum = 1;
  if (params.name == "全部") {
    initParam.dict_id = undefined;
    initParam.dict_type = undefined;
  } else if (params.code) {
    initParam.dict_id = params.id;
    initParam.dict_type = params.type;
  } else {
    initParam.dict_id = undefined;
    initParam.dict_type = params.type;
  }
};

const deleteDict = async (row: Recordable) => {
  await useHandleData(deleteDictByIdApi, row.id, `删除【${row.name}】字典配置`);
  await getTreeData();
};

const dictRef = ref();
const openDialog = (title: string, rowData: object) => {
  console.log(rowData);
  let params = {
    title,
    rowData: { ...rowData },
    isView: title === "查看",
    api: title === "新增" ? addDictApi : title === "编辑" ? editDictApi : "",
    updateTreeData: getTreeData
  };
  dictRef.value.acceptParams(params);
};

const getTableList = (params: any) => {
  const newParams = processParams(params);
  return dictValuePageListApi(newParams);
};

// 处理参数
const processParams = (params: any) => {
  return JSON.parse(JSON.stringify(params));
};

// 获取 ProTable 元素，调用其获取刷新数据方法（还能获取到当前查询参数，方便导出携带参数）
const proTable = ref();

// 删除字典配置值信息
const deleteDictValue = async (row: Recordable) => {
  await useHandleData(deleteDictValueByIdApi, row.id, `删除【${row.name}】字典配置值`);
  proTable.value.getTableList();
};

// 批量删除字典配置值信息
const batchDeleteValue = async (ids: string[]) => {
  await useHandleData(deleteDictValueApi, { ids }, "删除所选字典配置值信息");
  proTable.value.clearSelection();
  proTable.value.getTableList();
};

// 切换状态
const changeStatus = async (row: Recordable) => {
  if (!authButton("/dict/value/change_status/*")) {
    return;
  }
  await useHandleData(changeValueStatusApi, row.id, `切换【${row.name}】字典配置值状态`);
  proTable.value.getTableList();
};

// 修改字典配置值排序
const changeSort = async (val: number, row: Recordable) => {
  if (!authButton("/dict/value/changeSort")) {
    return;
  }
  await useHandleData(changeValueSortApi, { id: row.id, sort: val }, `修改【${row.name}】字典配置值排序`);
  proTable.value.getTableList();
};

const otherTextRef = ref();

const editOtherText = (row: Recordable) => {
  row.isEdit = true;
  row.otherTextBefore = row.otherText;
  nextTick(() => {
    otherTextRef.value.focus();
  });
};

// 修改字典配置值其它说明
const changeOtherText = async (val: string, row: Recordable) => {
  if (!authButton("/dict/value/changeOtherText")) {
    return;
  }
  await useHandleData(changeValueOtherTextApi, { id: row.id, otherText: val }, `修改【${row.name}】字典配置值其它说明`)
      .then(() => {
        proTable.value.getTableList();
      })
      .catch(() => {
        row.otherText = row.otherTextBefore;
        row.isEdit = false;
      });
};

// 打开 drawer(新增、查看、编辑)
const dictValueRef = ref();
const openDrawer = (title: string, rowData: Partial<Recordable> = {}) => {
  console.log(rowData);
  if (!rowData.dict_id) {
    ElMessage.error({ message: `请先选择字典类型` });
    return;
  }
  let params = {
    title,
    rowData: { ...rowData },
    isView: title === "查看",
    dictList: dictList.value,
    api: title === "新增" ? addDictValueApi : title === "编辑" ? editDictValueApi : "",
    getTableList: proTable.value.getTableList
  };
  dictValueRef.value.acceptParams(params);
};
</script>

<style lang="scss" scoped>
:deep(.el-tree-node__label) {
  display: inline-block;
  width: calc(100% - 88px);
  overflow: hidden;
}
:deep(.el-tree-node) {
  position: relative;
  &.is-current > .el-tree-node__content {
    button {
      color: #fff;
    }
  }
}
.custom-operation {
  position: absolute;
  top: 5px;
  right: 5px;
}
:deep(.el-table__cell) {
  .column-edit-icon {
    display: none;
  }
  &:hover {
    .column-edit-icon {
      display: inline;
      padding: 2px 5px;
      position: absolute;
      top: 14px;
      right: 5px;
    }
  }
}

:deep(.el-dialog .el-dialog__header) {
  margin-bottom: 16px;
}
</style>
